﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core;
using COFE.Core.Lister;
using NUnit.Framework;
using COFE.Core.Utils;

namespace COFE.Core.Profile
{
    public class VolumeRegistrar : IVolumeRegistrar
    {
        #region Constructor

        static VolumeRegistrar()
        {
            
        }

        public VolumeRegistrar()
        {

        }

        #endregion

        #region Methods

        public static void RegisterVolumeFactory(IFactory<IDirectoryLister> listerFactory)
        {
            Assert.IsNotNull(listerFactory);
            Assert.IsNotNullOrEmpty(listerFactory.FactoryKey);

            //lock (_registeredFactories)
            //    if (!_registeredFactories.ContainsKey(listerFactory.FactoryKey))
            //        _registeredFactories.Add(listerFactory.FactoryKey, listerFactory);
            FactoryRegister<IDirectoryLister>.RegisterFactory(listerFactory.FactoryKey, listerFactory);
        }

        public virtual void RegisterFactory(IFactory<IDirectoryLister> listerFactory)
        {
            RegisterVolumeFactory(listerFactory);
        }
        
        public virtual void RegisterVolume(IVolume volume)
        {
            lock (_registeredVolumes)
                if (!_registeredVolumes.ContainsKey(volume.ListerKey))
                    _registeredVolumes.Add(volume.ListerKey, volume);
                else _registeredVolumes[volume.ListerKey] = volume; 
        }

        public virtual IVolume ConstructVolume(string factoryKey, IDirectoryLister lister, 
            VolumeAccessMode defAccessMode)
        {
            return new Volume(factoryKey, lister, null, defAccessMode);
        }

        public virtual IVolume ConstructVolume(string factoryKey, string listerKey,
            string paramString, VolumeAccessMode defAccessMode)
        {
            Assert.IsNotNullOrEmpty(factoryKey);
            Assert.IsNotNullOrEmpty(listerKey);
            
            IFactory<IDirectoryLister> factory;
            factory = FactoryRegister<IDirectoryLister>.FindFactory(factoryKey);
            if (factory == null)
                throw new ArgumentException("Factory not found : " + factoryKey);            

            IDirectoryLister lister = factory.Construct(listerKey, paramString);
            IVolume volume = ConstructVolume(factoryKey, lister, defAccessMode);            
            return volume;
        }

        public virtual void RemoveVolume(string volumeId)
        {
            lock (_registeredVolumes)
                if (_registeredVolumes.ContainsKey(volumeId))
                    _registeredVolumes.Remove(volumeId);
        }

        public virtual IVolume LookupRegisterVolume(string listerKey)
        {
            lock (_registeredVolumes)
            {
                if (!_registeredVolumes.ContainsKey(listerKey))
                    return null;
                return _registeredVolumes[listerKey];
            }
        }


        #endregion

        #region Data

        //static Dictionary<string, IFactory<IDirectoryLister>> _registeredFactories = new Dictionary<string, IFactory<IDirectoryLister>>();
        Dictionary<string, IVolume> _registeredVolumes = new Dictionary<string, IVolume>();

        #endregion

        #region Public Properties
        
        public virtual Dictionary<string, IVolume> Volumes { get { return _registeredVolumes; } }
        public virtual Dictionary<string, IFactory<IDirectoryLister>> Factories { get { return FactoryRegister<IDirectoryLister>.Factories; } }

        #endregion








    }
}
